/*
 *所有关于Tb_Project_Templatesubject_Relationship类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*Tb_Project_Templatesubject_RelationshipService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using MYData.Entity.DomainModels;
using System.Linq;
using MYData.Core.Utilities;
using MYData.Core.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using MYData.System.IRepositories;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using MYData.Core.Enums;
using MYData.Entity.DTO.ApiEntity.OutPut;
using MYData.Core.EFDbContext;
using MYData.Entity.DTO.ApiEntity.Input;
using Mapster;
using System.Text;
using Snowflake.Core;
using NuGet.Packaging;

namespace MYData.System.Services
{
    public partial class Tb_Project_Templatesubject_RelationshipService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ITb_Project_Templatesubject_RelationshipRepository _repository;//访问数据库
        private readonly VOLContext _context;

        [ActivatorUtilitiesConstructor]
        public Tb_Project_Templatesubject_RelationshipService(
            ITb_Project_Templatesubject_RelationshipRepository dbRepository,
            IHttpContextAccessor httpContextAccessor
,
            VOLContext context)
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _context = context;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        WebResponseContent webResponse = new WebResponseContent();

        /// <summary>
        /// 根据模板Id获取经费模板科目(直接经费跟间接经费，子集跟在父级身后)
        /// </summary>
        /// <param name="fundtemplateId"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> Get_Fundtemplate_ItemList(string fundtemplateId)
        {
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_DtoZ = new List<ProjectFundingItemOutput_Dto>();
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_DtoJ = new List<ProjectFundingItemOutput_Dto>();
            //List<Tb_Project_Templatesubject_Relationship>
            //根据模板Id获取关系表中的数据
            var relationshiplist = _repository.FindAsIQueryable(x => x.fundtemplateId.Equals(fundtemplateId));
            //获取所有直接经费科目的Id
            string[] IdArrayZ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayZ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true)).Select(x => x.supportingBudgetId).FirstOrDefault().Split(',');
            //获取所有间接经费的Id
            string[] IdArrayJ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayJ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId)?.FirstOrDefault().Split(',');
            //获取所有直接经费
            var ListZ = GetSubjectTemp(IdArrayZ);
            //直接经费分类
            project_Fundtemplate_DtoZ.AddRange(Subjectclassify2(ListZ, "0"));
            //获取所有间接经费
            var ListJ = GetSubjectTemp(IdArrayJ);
            //间接经费分类
            project_Fundtemplate_DtoJ.AddRange(Subjectclassify2(ListJ, "0"));
            //project_Fundtemplate_DtoJ.AddRange(GetChildren(IdArrayJ));
            object res = new { DirectFunding = project_Fundtemplate_DtoZ, IndirectCosts = project_Fundtemplate_DtoJ };
            return webResponse.OK("经费模板获取成功", res);
        }
        /// <summary>
        /// 获取儿子
        /// </summary>
        /// <param name="IdArray"></param>
        /// <returns></returns>
        private List<ProjectFundingItemOutput_Dto> GetChildren(string[] IdArray)
        {
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_Dto = new List<ProjectFundingItemOutput_Dto>();
            foreach (string id in IdArray)
            {
                if (id != "##")
                {
                    //获取模板科目表信息
                    var funtemplatelist = _context.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.budgetItemId.Equals(id)).FirstOrDefault();
                    if (funtemplatelist != null)
                        project_Fundtemplate_Dto.Add(new ProjectFundingItemOutput_Dto
                        {
                            budgetItemId = funtemplatelist.budgetItemId,
                            budgetitemName = funtemplatelist.budgetitemName,
                            budgetType = funtemplatelist.budgetType,
                            partentId = funtemplatelist.partentId,
                            children = GetGrandson(funtemplatelist.budgetItemId)
                        });
                }
            }
            return project_Fundtemplate_Dto;
        }
        /// <summary>
        /// 获取孙子
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private List<ProjectFundingItemOutput_Dto> GetGrandson(string id)
        {
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_Dto = new List<ProjectFundingItemOutput_Dto>();
            //获取模板科目表信息
            var funtemplatelist = _context.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.partentId.Equals(id) && x.budgetiState.Equals(0)).ToList();
            foreach (var item in funtemplatelist)
            {
                project_Fundtemplate_Dto.Add(new ProjectFundingItemOutput_Dto
                {
                    budgetItemId = item.budgetItemId,
                    budgetitemName = item.budgetitemName,
                    budgetType = item.budgetType,
                    partentId = item.partentId,
                    children = GetGrandson(item.budgetItemId)
                });
            };
            return project_Fundtemplate_Dto;
        }

        /// <summary>
        /// 获取所有的科目模板
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> GetFundingItemList()
        {
            //直接经费
            List<ProjectFundingItemOutput_Dto> projectFundingItemOutputDtoZ = GetGrandson("0").Where(x => x.budgetType.Equals(true) && x.budgetiState.Equals(0)).ToList();
            //间接经费
            List<ProjectFundingItemOutput_Dto> projectFundingItemOutputDtoJ = GetGrandson("0").Where(x => x.budgetType.Equals(false) && x.budgetiState.Equals(0)).ToList();
            object res = new { DirectFunding = projectFundingItemOutputDtoZ, IndirectCosts = projectFundingItemOutputDtoJ };
            return webResponse.OK("预算科目获取成功", res);
        }
        /// <summary>
        /// 获取所有的科目模板（根据所有一级的科目模板，带儿子）
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> GetFundingItemListAll()
        {
            List<ProjectFundingItemOutput_Dto> projectFundingItemOutputDto = GetGrandson("0").Where(x => x.budgetiState.Equals(0)).ToList();
            return webResponse.OK("预算科目获取成功", projectFundingItemOutputDto);
        }

        /// <summary>
        /// 添加模板科目关系表
        /// </summary>
        /// <returns></returns>
        public async Task<WebResponseContent> InsertTemplateSubjectItemsAsync(TemplateSubjectItemInput_Dto inputDto)
        {
            //把Dto转换为实体
            var model = inputDto.Adapt<Tb_Project_Templatesubject_Relationship>();
            _repository.Add(model);
            return webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChanges());
        }

        /// <summary>
        /// 修改模板科目关系表
        /// </summary>
        /// <returns></returns>
        public async Task<WebResponseContent> UpdateTemplateSubjectItemsAsync(List<UpdatefundingItem_dto> inputDto)
        {
            //把Dto转换为实体
            var model = inputDto.Adapt<List<Tb_Project_Templatesubject_Relationship>>();
            foreach (var item in model)
            {
                _repository.Update(item);
            }
            return webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChanges());
        }

        /// <summary>
        /// 根据模板id获取经费科目(子集在父级身后)，
        /// 传出值：所有直接经费、所有间接经费，当前模板下要选中的科目，
        /// 直接经费模板关系表的Id，间接经费模板关系表的Id
        /// MJZ 2023/03/31 15:15
        /// </summary>
        /// <param name="fundtemplateId"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> GetBudgeSubject(string fundtemplateId)
        {
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_Dto = new List<ProjectFundingItemOutput_Dto>();
            //根据模板Id获取关系表中的数据
            var relationshiplist = _repository.FindAsIQueryable(x => x.fundtemplateId.Equals(fundtemplateId));
            //获取所有直接经费科目的Id
            string[] IdArrayZ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayZ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true)).Select(x => x.supportingBudgetId).FirstOrDefault().Split(',');
            //获取所有间接经费的Id
            string[] IdArrayJ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayJ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId)?.FirstOrDefault().Split(',');
            //获取所有直接经费
            project_Fundtemplate_Dto.AddRange(GetChildren(IdArrayZ));
            project_Fundtemplate_Dto.AddRange(GetChildren(IdArrayJ));

            //直接经费
            List<ProjectFundingItemOutput_Dto> projectFundingItemOutputDtoZ = GetGrandson("0").Where(x => x.budgetType.Equals(true) && x.budgetiState.Equals(0)).ToList();
            //间接经费
            List<ProjectFundingItemOutput_Dto> projectFundingItemOutputDtoJ = GetGrandson("0").Where(x => x.budgetType.Equals(false) && x.budgetiState.Equals(0)).ToList();

            object res = new { DirectFunding = projectFundingItemOutputDtoZ, IndirectCosts = projectFundingItemOutputDtoJ, project_Fundtemplate_Dto = project_Fundtemplate_Dto, RelationshipIdZ = relationshiplist.FirstOrDefault(x => x.supportingBudgetTypeId.Equals(true)).Id, RelationshipIdJ = relationshiplist.FirstOrDefault(x => x.supportingBudgetTypeId.Equals(false)).Id };

            return webResponse.OK("经费模板获取成功", res);
        }

        /// <summary>
        /// 根据模板Id获取经费科目（子集不在父级身后，选中的子集在父级身后）
        ///  MJZ 2023/4/2 10:18
        /// </summary>
        /// <param name="fundtemplateId"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> GetBudgeSubjectTemp(string fundtemplateId)
        {
            //根据模板Id获取关系表中的数据
            var relationshiplist = _repository.FindAsIQueryable(x => x.fundtemplateId.Equals(fundtemplateId));
            //获取所有直接经费科目的Id
            string[] IdArrayZ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayZ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true)).Select(x => x.supportingBudgetId).FirstOrDefault().Split(',');
            //获取所有间接经费的Id
            string[] IdArrayJ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayJ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId)?.FirstOrDefault().Split(',');
            //获取该模板下所有预算科目的id
            string[] IdArray = IdArrayZ.Concat(IdArrayJ).ToArray();
            //IdArrayZ.AddRange(IdArrayJ);
            List<ProjectFundingItemOutput_Dto> subjectTrmp = GetSubjectTemp(IdArray);
            List<ProjectFundingItemOutput_Dto> output_Dtos = Subjectclassify(subjectTrmp, "0").ToList();
            return webResponse.OK("模板预算科目获取成功", output_Dtos);
        }
        /// <summary>
        /// 根据模板ID获取其下科目
        /// 同步
        /// </summary>
        /// <param name="fundtemplateId"></param>
        /// <returns></returns>
        public List<ProjectFundingItemOutput_Dto> GetBudgeSubjectTemp2(string fundtemplateId)
        {
            //根据模板Id获取关系表中的数据
            var relationshiplist = _repository.FindAsIQueryable(x => x.fundtemplateId.Equals(fundtemplateId));
            //获取所有直接经费科目的Id
            string[] IdArrayZ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayZ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(true)).Select(x => x.supportingBudgetId).FirstOrDefault().Split(',');
            //获取所有间接经费的Id
            string[] IdArrayJ = { };
            if (relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId).FirstOrDefault() != null)
                IdArrayJ = relationshiplist.Where(x => x.supportingBudgetTypeId.Equals(false))?.Select(x => x.supportingBudgetId)?.FirstOrDefault().Split(',');
            //获取该模板下所有预算科目的id
            string[] IdArray = IdArrayZ.Concat(IdArrayJ).ToArray();
            //IdArrayZ.AddRange(IdArrayJ);
            List<ProjectFundingItemOutput_Dto> subjectTrmp = GetSubjectTemp(IdArray);
            List<ProjectFundingItemOutput_Dto> output_Dtos = Subjectclassify(subjectTrmp, "0").ToList();
            return output_Dtos;
        }

        /// <summary>
        /// 根据该模板下所有预算科目的id获取所有该模板下的预算科目
        /// MJZ 2023/4/2 10:18
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private List<ProjectFundingItemOutput_Dto> GetSubjectTemp(string[] IdArray)
        {
            List<ProjectFundingItemOutput_Dto> project_Fundtemplate_Dto = new List<ProjectFundingItemOutput_Dto>();
            foreach (string id in IdArray)
            {
                if (id != "##")
                {
                    //获取模板科目表信息
                    var funtemplatelist = _context.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.budgetItemId.Equals(id)).FirstOrDefault();
                    if (funtemplatelist != null)
                        project_Fundtemplate_Dto.Add(new ProjectFundingItemOutput_Dto
                        {
                            budgetItemId = funtemplatelist.budgetItemId,
                            budgetitemName = funtemplatelist.budgetitemName,
                            budgetType = funtemplatelist.budgetType,
                            partentId = funtemplatelist.partentId,
                            // children = GetGrandson(funtemplatelist.budgetItemId)
                        });
                }
            }
            return project_Fundtemplate_Dto;
        }

        /// <summary>
        /// 科目分类
        ///  MJZ 2023/4/2 10:18
        /// </summary>
        /// <param name="list"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private List<ProjectFundingItemOutput_Dto> Subjectclassify(List<ProjectFundingItemOutput_Dto> list, string parentId)
        {
            List<ProjectFundingItemOutput_Dto> projectFundings = list.Where(x => x.partentId.Equals(parentId) && x.budgetiState.Equals(0)).ToList();
            List<ProjectFundingItemOutput_Dto> SubjectTemp = new List<ProjectFundingItemOutput_Dto>();
            foreach (var item in projectFundings)
            {
                SubjectTemp.Add(new ProjectFundingItemOutput_Dto
                {
                    budgetItemId = item.budgetItemId,
                    budgetitemName = item.budgetitemName,
                    budgetType = item.budgetType,
                    partentId = item.partentId,
                    children = Subjectclassify(list, item.budgetItemId)
                });
            }
            return SubjectTemp;
        }
        private List<ProjectFundingItemOutput_Dto> Subjectclassify2(List<ProjectFundingItemOutput_Dto> list, string parentId)
        {
            List<ProjectFundingItemOutput_Dto> projectFundings = list.Where(x => x.partentId.Equals(parentId) && x.budgetiState.Equals(0)).ToList();
            List<ProjectFundingItemOutput_Dto> SubjectTemp = new List<ProjectFundingItemOutput_Dto>();
            foreach (var item in projectFundings)
            {
                SubjectTemp.Add(new ProjectFundingItemOutput_Dto
                {
                    budgetItemId = item.budgetItemId,
                    budgetitemName = item.budgetitemName,
                    budgetType = item.budgetType,
                    partentId = item.partentId,
                    children = Subjectclassify2(list, item.budgetItemId)
                });
                SubjectTemp.AddRange(Subjectclassify2(list, item.budgetItemId));
            };
            return SubjectTemp;
        }
        //public List<WebResponseContent> ExpenseReimbursement()
        //{

        //}
    }
}
